<?php
/**
 * Author: LaiGuiming
 * Time: 2017-07-21 10:41
 * Copyright (C) 2016 Longyan Wehome Message CO.,LTD.
 */

namespace app\common\lib;
use app\admin\model\Cron;
use think\console\Command;
use think\console\Input;
use think\console\Output;

/**
 * 计划调度逻辑类
 * Class Crond
 * @package app\common\lib
 */
class Crond extends Command
{
    protected function configure()
    {
        $this->setName('Cron')
            ->setDescription('计划任务');
    }

    protected function execute(Input $input, Output $output)
    {
        $this->doCron();
        $output->writeln("已经执行计划任务");
    }

    public function doCron()
    {
        //logger("检测计划调度执行...");
        // 记录开始运行的时间
        //$GLOBALS['_beginTime'] = microtime(TRUE);

        /* 永不超时 */
        ini_set('max_execution_time', 0);
        $time   = time();
        $exe_method = [];
        //获取计划调度数据
        $crond_list=array();
        $cron=new Cron();
        $cron_data=$cron->where("status=0")->field("format,method")->select();
        foreach ($cron_data as $item){
            if(count($crond_list)==0){
                $cron1=array();
                array_push($cron1,$item->method);
                $crond_list[$item->format]=$cron1;
            }else{
                if(array_key_exists($item->format,$crond_list)){
                    $cron2=$crond_list[$item->format];
                    array_push($cron2,$item->method);
                    $crond_list[$item->format]=$cron2;
                }else{
                    $cron1=array();
                    array_push($cron1,$item->method);
                    $crond_list[$item->format]=$cron1;
                }
            }
        }
        //获取计划调度格式
        $sys_crond_timer = array('*', '*:i', 'H:i', '@-w H:i', '*-d H:i', 'm-d H:i', 'Y-m-d H:i');;
        foreach ( $sys_crond_timer as $format )
        {
            $key = date($format, ceil($time));
            if ( is_array(@$crond_list[$key]) )
            {
                $exe_method = array_merge($exe_method, $crond_list[$key]);
            }
        }
        //循环执行方法
        if (!empty($exe_method))
        {
            foreach ($exe_method as $method)
            {
                if(!is_callable($method))
                {
                    //方法不存在的话就跳过不执行
                    continue;
                }
                $runtime_start = microtime(true);
                call_user_func($method);
                $runtime = microtime(true) - $runtime_start;
                logger("执行计划调度方法【{$method}()】完成, 执行时间: {$runtime}");
            }
            //$time_total = microtime(true) - $GLOBALS['_beginTime'];
            //logger("本次总执行时间:{$time_total}");
        }
    }
}